package com.symaster.common.swing.element.combo.box;

import com.symaster.common.swing.config.AppConfig;
import com.symaster.common.swing.element.list.SwingListAbs;
import com.symaster.common.swing.element.list.SwingListPanel;
import com.symaster.common.swing.style.Style;
import com.symaster.common.swing.util.SwingUtil;
import com.symaster.common.swing.util.ThreadPoolUtil;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.*;

/**
 * @author yinmiao
 * @date 2022-01-26 10:09
 */
public class MyComboBox extends JPanel {

    private static final ImageIcon triangle = SwingUtil.loadIconEnabledCache("triangle.png", 13, 13);
    private JPanel root_panel;
    private JTextField center_text;
    private JPanel right_panel;
    private JButton icon_button;
    private List<SelectItem> selectItems;
    private Dialog selectPanel;
    private SelectItem thatSelectItem;
    private Set<SelectListener> selectListeners;
    private Date closeTime;
    private boolean enabled = true;

    /**
     * Creates a new <code>JPanel</code> with a double buffer
     * and a flow layout.
     */
    public MyComboBox() {
        initPage();
        initListener();
    }

    private void initListener() {
        icon_button.addActionListener((e) -> openSelectPanel(this.selectItems));
        center_text.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                openSelectPanel(selectItems);
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });
    }

    private void initPage() {
        setLayout(new BorderLayout());
        add(root_panel);
        center_text.setBackground(AppConfig.getColor("auxiliary_background_color"));
        center_text.setDisabledTextColor(AppConfig.getColor("select_color"));
        icon_button.setBackground(AppConfig.getColor("auxiliary_background_color"));
        icon_button.setIcon(triangle);
        center_text.setText("请选择");
        Style.setFont(1, center_text);
        Style.setBorder(1, center_text, icon_button);
    }

    @Override
    public void setEnabled(boolean enabled) {
        // super.setEnabled(enabled);
        this.enabled = enabled;
        if (!enabled) {
            center_text.setBackground(AppConfig.getColor("main_background_color"));
            right_panel.setBackground(AppConfig.getColor("main_background_color"));
        } else {
            center_text.setBackground(AppConfig.getColor("auxiliary_background_color"));
            right_panel.setBackground(AppConfig.getColor("auxiliary_background_color"));
        }
        icon_button.setVisible(enabled);
    }

    public void setSelectPanel(List<SelectItem> selectItems) {
        this.selectItems = selectItems;
    }

    public void openSelectPanel(List<SelectItem> selectItems) {

        if (!enabled) {
            return;
        }

        if (closeTime != null && System.currentTimeMillis() - closeTime.getTime() < 500) {
            return;
        }

        int selectItemHeight = 27;
        Dimension size = this.getSize();
        int width = (int) size.getWidth();
        int height = 27;
        if (selectItems != null && selectItems.size() > 0) {
            height += selectItems.size() * selectItemHeight;
        }

        setSelectPanelBounds(width, height);
        SwingListPanel swingListPanel = getSwingListPanel(selectItemHeight, width);

        SelectItem selectItem = new SelectItem("请选择");
        selectItem.setOtherConfig("$$$$_null_$$$$");
        if (thatSelectItem == null) {
            selectItem.getText().setDisabledTextColor(AppConfig.getColor("select_color"));
        }
        swingListPanel.put(selectItem);

        putItem(selectItems, swingListPanel);

        selectPanel.pack();
        selectPanel.setVisible(true);
        selectPanel.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {

            }

            @Override
            public void focusLost(FocusEvent e) {
                closeSelectPanel();
            }
        });
    }

    private void putItem(List<SelectItem> selectItems, SwingListPanel swingListPanel) {
        if (selectItems != null && selectItems.size() > 0) {
            for (SelectItem item : selectItems) {
                item.getText().setDisabledTextColor(AppConfig.getColor("auxiliary_font_color"));
                if (thatSelectItem != null) {
                    String uuid = item.getUuid();
                    String uuid1 = this.thatSelectItem.getUuid();
                    if (uuid1.equals(uuid)) {
                        item.getText().setDisabledTextColor(AppConfig.getColor("select_color"));
                    }
                }
                swingListPanel.put(item);
            }
        }
    }

    /**
     * 选择项目事件
     */
    public void selectPanelListener(SelectItem selectItem) {
        if ("$$$$_null_$$$$".equals(selectItem.getOtherConfig())) {
            this.thatSelectItem = null;
        } else {
            this.thatSelectItem = selectItem;
        }

        closeSelectPanel();
        center_text.setText(selectItem.getName());

        if (selectListeners == null || selectListeners.size() <= 0) {
            return;
        }
        for (SelectListener selectListener : selectListeners) {
            ThreadPoolUtil.execute(() -> selectListener.handler(("$$$$_null_$$$$".equals(selectItem.getOtherConfig())) ? null : selectItem));
        }
    }

    private void setSelectPanelBounds(int width, int height) {
        selectPanel = new JDialog();
        Dimension dimension = new Dimension(width, height);
        selectPanel.setPreferredSize(dimension);
        selectPanel.setUndecorated(true);
        Point location = getLocationOnScreen();
        selectPanel.setBounds((int) location.getX(), (int) location.getY() - height, width, height);
    }

    private SwingListPanel getSwingListPanel(int selectItemHeight, int width) {
        SwingListPanel swingListPanel = new SwingListPanel(width, selectItemHeight, AppConfig.getColor("auxiliary_background_color"), 0, 0);
        selectPanel.setLayout(new BorderLayout());
        selectPanel.add(swingListPanel);
        swingListPanel.addSelectElementListener(select -> selectPanelListener((SelectItem) select));
        return swingListPanel;
    }

    public void closeSelectPanel() {
        this.closeTime = new Date();
        selectPanel.setVisible(false);
    }

    public SelectItem getSelectItem() {
        return thatSelectItem;
    }

    public void addSelectListener(SelectListener listener) {
        if (selectListeners == null) {
            selectListeners = new HashSet<>();
        }
        selectListeners.add(listener);
    }

    public void removeSelectListener(SelectListener listener) {
        if (selectListeners == null || selectListeners.size() <= 0) {
            return;
        }
        selectListeners.remove(listener);
    }

    {
        // GUI initializer generated by IntelliJ IDEA GUI Designer
        // >>> IMPORTANT!! <<<
        // DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        root_panel = new JPanel();
        root_panel.setLayout(new BorderLayout(0, 0));
        root_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(-11184294)), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        center_text = new JTextField();
        center_text.setEditable(false);
        center_text.setEnabled(false);
        center_text.setHorizontalAlignment(0);
        root_panel.add(center_text, BorderLayout.CENTER);
        right_panel = new JPanel();
        right_panel.setLayout(new BorderLayout(0, 0));
        right_panel.setPreferredSize(new Dimension(25, 0));
        root_panel.add(right_panel, BorderLayout.EAST);
        right_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        icon_button = new JButton();
        icon_button.setFocusPainted(false);
        icon_button.setText("");
        right_panel.add(icon_button, BorderLayout.CENTER);
    }

    /** @noinspection ALL */
    public JComponent $$$getRootComponent$$$() {
        return root_panel;
    }

    public interface SelectListener extends EventListener {
        void handler(SelectItem selectItem);
    }

    public static class SelectItem extends SwingListAbs {

        private final JTextField text;
        private String name;
        private String otherConfig;

        public SelectItem(String name) {
            this.name = name;
            setLayout(new BorderLayout());
            text = SwingUtil.getText(name);
            text.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    select();
                }

                @Override
                public void mousePressed(MouseEvent e) {

                }

                @Override
                public void mouseReleased(MouseEvent e) {

                }

                @Override
                public void mouseEntered(MouseEvent e) {

                }

                @Override
                public void mouseExited(MouseEvent e) {

                }
            });
            add(text);
        }

        public JTextField getText() {
            return text;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public void setName(String name) {
            this.name = name;
        }

        public String getOtherConfig() {
            return otherConfig;
        }

        public void setOtherConfig(String otherConfig) {
            this.otherConfig = otherConfig;
        }

        @Override
        public String toString() {
            return "SelectItem{" +
                    "name='" + name + '\'' +
                    ", otherConfig='" + otherConfig + '\'' +
                    '}';
        }
    }

}
